#include <stdlib.h>
#include <stdio.h>
#include <jni.h>

#include "ffmpeg.h"

// 指定要注册的类，对应完整的java类名
#define JNIREG_CLASS "org/wysaid/nativePort/FilterProcessLibrary"
#ifndef NELEM
#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
#endif


char *ffmpeg_jstringTostr(JNIEnv *env, jstring jstr) {
    char *pStr = NULL;
    jclass jstrObj = (*env)->FindClass(env, "java/lang/String");
    jstring encode = (*env)->NewStringUTF(env, "utf-8");
    jmethodID methodId = (*env)->GetMethodID(env, jstrObj, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray byteArray = (jbyteArray) (*env)->CallObjectMethod(env, jstr, methodId, encode);
    jsize strLen = (*env)->GetArrayLength(env, byteArray);
    jbyte *jBuf = (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
    if (jBuf > 0) {
        pStr = (char *) malloc(strLen + 1);
        if (!pStr) {
            return NULL;
        }
        memcpy(pStr, jBuf, strLen);
        pStr[strLen] = 0;
    }
    (*env)->ReleaseByteArrayElements(env, byteArray, jBuf, 0);
    return pStr;
}

JNIEXPORT jint JNICALL native_transcoding(JNIEnv *env, jobject classzz, jstring inputPath,
                                          jstring filter, jstring ouputpath) {
    char *fileinputpath = ffmpeg_jstringTostr(env, inputPath);
    char *fileoutputpath = ffmpeg_jstringTostr(env, ouputpath);
    char *filter_descr = ffmpeg_jstringTostr(env, filter);
    return ffmpeg_transcoding(fileinputpath, filter_descr, fileoutputpath);
}

JNIEXPORT jint JNICALL native_transcoding_only(JNIEnv *env, jobject classzz, jstring inputPath, jstring ouputpath) {
    char *fileinputpath = ffmpeg_jstringTostr(env, inputPath);
    char *fileoutputpath = ffmpeg_jstringTostr(env, ouputpath);
    return ffmpeg_transcoding_only(fileinputpath, fileoutputpath);
}


//Java和JNI函数的绑定
static JNINativeMethod method_table[] = {
        {"_transcoding", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I", (void *) native_transcoding},
        {"_transcoding_only", "(Ljava/lang/String;Ljava/lang/String;)I", (void *) native_transcoding_only},
};

//注冊native方法到java中
static int registerNativeMethods(JNIEnv *env, const char *className,
                                 JNINativeMethod *gMethods, int numMethods) {
    jclass clazz;
    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL) {
        return JNI_FALSE;
    }
    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

//调用注册方法
int register_ndk_load(JNIEnv *env) {
    return registerNativeMethods(env, JNIREG_CLASS, method_table, NELEM(method_table));
}

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    jint result = -1;
    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        return result;
    }
    register_ndk_load(env);
    //返回JNI的版本
    return JNI_VERSION_1_6;
}

